ALTER TABLE empleado ADD constraint CategoriaValida check(categoria < 3 AND categoria >= 0);

CREATE FUNCTION CheckEmpleadoEsProfesional() RETURNS trigger AS '
BEGIN
  IF (SELECT 
          categoria 
      FROM 
          empleado 
      WHERE 
          empleado_id = NEW.empleado_id
      ) != 0 THEN
    RAISE EXCEPTION ''Solo se puede insertar empleados no profesionales en empleado_no_profesional.'';
  END IF;
  RETURN NEW;    
END' LANGUAGE plpgsql;
    
CREATE TRIGGER EmpleadoNoProfesional
  BEFORE INSERT OR UPDATE ON empleado_no_profesional
  FOR EACH ROW
  EXECUTE PROCEDURE CheckEmpleadoEsProfesional();


CREATE FUNCTION CheckEmpleadoJerarquico() RETURNS trigger AS '
BEGIN
  IF (SELECT
        categoria
      FROM
        empleado
      WHERE
        empleado_id = NEW.empleado_id
      ) != 1 THEN
    RAISE EXCEPTION ''Solo se puede agregar personal jerarquico a empleado_jerarquico.'';
  END IF;
  RETURN NEW;
END' LANGUAGE plpgsql;

CREATE TRIGGER EmpleadoJerarquico
  BEFORE INSERT OR UPDATE ON empleado_jerarquico
  FOR EACH ROW
  EXECUTE PROCEDURE CheckEmpleadoJerarquico();

CREATE FUNCTION CheckEmpleadoProfesional() RETURNS trigger AS '
BEGIN
  IF (SELECT
        categoria
      FROM
        empleado
      WHERE
        empleado_id = NEW.empleado_id
      ) != 2 THEN
    RAISE EXCEPTION ''Solo se puede agregar personal profesional a empleado_profesional.'';
  END IF;
  RETURN NEW;
END' LANGUAGE plpgsql;

CREATE TRIGGER EmpleadoProfesional
  BEFORE INSERT OR UPDATE ON empleado_profesional
  FOR EACH ROW
  EXECUTE PROCEDURE CheckEmpleadoProfesional();


CREATE FUNCTION CheckProfesionalContratado() RETURNS trigger AS '
BEGIN
  IF (SELECT
        contratado
      FROM
        empleado_profesional
      WHERE
        empleado_id = NEW.empleado_id) != 1 THEN
    RAISE EXCEPTION ''Solo los profesionales contratados pueden ser agregados a empleado_profesional_contratado.'';
  END IF;
  RETURN NEW;
END' LANGUAGE plpgsql;

CREATE TRIGGER ProfesionalContratado
  BEFORE INSERT OR UPDATE ON empleado_profesional_contratado
  FOR EACH ROW
  EXECUTE PROCEDURE CheckProfesionalContratado();


CREATE FUNCTION CheckProfesionalPlantaPermanente() RETURNS trigger AS '
BEGIN
  IF (SELECT
        contratado
      FROM
        empleado_profesional
      WHERE
        empleado_id = NEW.empleado_id) != 0 THEN
    RAISE EXCEPTION ''Solo los profesionales de planta permanente pueden ser agregados a empleado_profesional_planta_permanente.'';
  END IF;
  RETURN NEW;
END' LANGUAGE plpgsql;

CREATE TRIGGER ProfesionalPlantaPermanente
  BEFORE INSERT OR UPDATE ON empleado_profesional_planta_permanente
  FOR EACH ROW
  EXECUTE PROCEDURE CheckProfesionalPlantaPermanente();


CREATE FUNCTION CheckAccesoPosibleValido() RETURNS trigger AS '
BEGIN
  IF (SELECT 
        nivel_seguridad_id 
      FROM 
        area
      WHERE
        area_id = NEW.area_id) >
     (SELECT 
        nivel_seguridad_id
      FROM
        empleado_no_profesional
      WHERE
        empleado_id = NEW.empleado_id) THEN
    RAISE EXCEPTION ''Este usuario no tiene permisos suficientes como para poder acceder a esta area.'';
  END IF;
  RETURN NEW;
END' LANGUAGE plpgsql;


CREATE TRIGGER AccesoPosibleValido
  BEFORE INSERT OR UPDATE ON empleado_no_profesional_acceso
  FOR EACH ROW
  EXECUTE PROCEDURE CheckAccesoPosibleValido();


CREATE FUNCTION CheckAccesoValido() RETURNS trigger AS '
BEGIN
  IF NEW.autorizado != 
     EXISTS(SELECT
              1
            FROM
              empleado_no_profesional_acceso
            WHERE
              empleado_id = NEW.empleado_id
              AND area_id = NEW.area_id) THEN
    RAISE EXCEPTION ''Este usuario no esta autorizado a acceder a este area.'';
  END IF;
  RETURN NEW;
END' LANGUAGE plpgsql;

CREATE TRIGGER AccesoValido
  BEFORE INSERT OR UPDATE ON acceso
  FOR EACH ROW
  EXECUTE PROCEDURE CheckAccesoValido();
